home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 September / PCWorld_2008-09_cd.bin / v cisle / sadanastroju / greasemonkey-0.8.20080609.0-fx.xpi / chrome / greasemonkey.jar / chromeFiles / content / utils.js < prev    next >
Text File  |  2008-06-09  |  13KB  |  432 lines

  1. const GM_GUID = "{e4a8a97b-f2ed-450b-b12d-ee082ba24781}";
  2.  
  3. // TODO: properly scope this constant
  4. const NAMESPACE = "http://youngpup.net/greasemonkey";
  5.  
  6. var GM_consoleService = Components.classes["@mozilla.org/consoleservice;1"]
  7.                         .getService(Components.interfaces.nsIConsoleService);
  8.  
  9. function GM_isDef(thing) {
  10.   return typeof(thing) != "undefined";
  11. }
  12.  
  13. function GM_getConfig() {
  14.   return Components
  15.     .classes["@greasemonkey.mozdev.org/greasemonkey-service;1"]
  16.     .getService(Components.interfaces.gmIGreasemonkeyService)
  17.     .wrappedJSObject.config;
  18. }
  19.  
  20. function GM_hitch(obj, meth) {
  21.   if (!obj[meth]) {
  22.     throw "method '" + meth + "' does not exist on object '" + obj + "'";
  23.   }
  24.  
  25.   var staticArgs = Array.prototype.splice.call(arguments, 2, arguments.length);
  26.  
  27.   return function() {
  28.     // make a copy of staticArgs (don't modify it because it gets reused for
  29.     // every invocation).
  30.     var args = staticArgs.concat();
  31.  
  32.     // add all the new arguments
  33.     for (var i = 0; i < arguments.length; i++) {
  34.       args.push(arguments[i]);
  35.     }
  36.  
  37.     // invoke the original function with the correct this obj and the combined
  38.     // list of static and dynamic arguments.
  39.     return obj[meth].apply(obj, args);
  40.   };
  41. }
  42.  
  43. function GM_listen(source, event, listener, opt_capture) {
  44.   Components.lookupMethod(source, "addEventListener")(
  45.     event, listener, opt_capture);
  46. }
  47.  
  48. function GM_unlisten(source, event, listener, opt_capture) {
  49.   Components.lookupMethod(source, "removeEventListener")(
  50.     event, listener, opt_capture);
  51. }
  52.  
  53. /**
  54.  * Utility to create an error message in the log without throwing an error.
  55.  */
  56. function GM_logError(e, opt_warn, fileName, lineNumber) {
  57.   var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
  58.     .getService(Components.interfaces.nsIConsoleService);
  59.  
  60.   var consoleError = Components.classes["@mozilla.org/scripterror;1"]
  61.     .createInstance(Components.interfaces.nsIScriptError);
  62.  
  63.   var flags = opt_warn ? 1 : 0;
  64.  
  65.   // third parameter "sourceLine" is supposed to be the line, of the source,
  66.   // on which the error happened.  we don't know it. (directly...)
  67.   consoleError.init(e.message, fileName, null, lineNumber,
  68.                     e.columnNumber, flags, null);
  69.  
  70.   consoleService.logMessage(consoleError);
  71. }
  72.  
  73. function GM_log(message, force) {
  74.   if (force || GM_prefRoot.getValue("logChrome", false)) {
  75.     GM_consoleService.logStringMessage(message);
  76.   }
  77. }
  78.  
  79. function GM_openUserScriptManager() {
  80.   var win = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  81.                       .getService(Components.interfaces.nsIWindowMediator)
  82.                       .getMostRecentWindow("Greasemonkey:Manage");
  83.   if (win) {
  84.     win.focus();
  85.   } else {
  86.     var parentWindow = (!window.opener || window.opener.closed) ?
  87.       window : window.opener;
  88.     parentWindow.openDialog("chrome://greasemonkey/content/manage.xul",
  89.       "_blank", "resizable,dialog=no,centerscreen");
  90.   }
  91. }
  92.  
  93. // TODO: this stuff was copied wholesale and not refactored at all. Lots of
  94. // the UI and Config rely on it. Needs rethinking.
  95.  
  96. function openInEditor(script) {
  97.   var file = script.editFile;
  98.   var stringBundle = Components
  99.     .classes["@mozilla.org/intl/stringbundle;1"]
  100.     .getService(Components.interfaces.nsIStringBundleService)
  101.     .createBundle("chrome://greasemonkey/locale/gm-browser.properties");
  102.   var editor = getEditor(stringBundle);
  103.   if (!editor) {
  104.     // The user did not choose an editor.
  105.     return;
  106.   }
  107.  
  108.   try {
  109.     launchApplicationWithDoc(editor, file);
  110.   } catch (e) {
  111.     // Something may be wrong with the editor the user selected. Remove so that
  112.     // next time they can pick a different one.
  113.     alert(stringBundle.GetStringFromName("editor.could_not_launch") + "\n" + e);
  114.     GM_prefRoot.remove("editor");
  115.     throw e;
  116.   }
  117. }
  118.  
  119. function getEditor(stringBundle) {
  120.   var editorPath = GM_prefRoot.getValue("editor");
  121.  
  122.   if (editorPath) {
  123.     GM_log("Found saved editor preference: " + editorPath);
  124.  
  125.     var editor = Components.classes["@mozilla.org/file/local;1"]
  126.                  .createInstance(Components.interfaces.nsILocalFile);
  127.     editor.followLinks = true;
  128.     editor.initWithPath(editorPath);
  129.  
  130.     // make sure the editor preference is still valid
  131.     if (editor.exists() && editor.isExecutable()) {
  132.       return editor;
  133.     } else {
  134.       GM_log("Editor preference either does not exist or is not executable");
  135.       GM_prefRoot.remove("editor");
  136.     }
  137.   }
  138.  
  139.   // Ask the user to choose a new editor. Sometimes users get confused and
  140.   // pick a non-executable file, so we set this up in a loop so that if they do
  141.   // that we can give them an error and try again.
  142.   while (true) {
  143.     GM_log("Asking user to choose editor...");
  144.     var nsIFilePicker = Components.interfaces.nsIFilePicker;
  145.     var filePicker = Components.classes["@mozilla.org/filepicker;1"]
  146.                                .createInstance(nsIFilePicker);
  147.  
  148.     filePicker.init(window, stringBundle.GetStringFromName("editor.prompt"),
  149.                     nsIFilePicker.modeOpen);
  150.     filePicker.appendFilters(nsIFilePicker.filterApplication);
  151.     filePicker.appendFilters(nsIFilePicker.filterAll);
  152.  
  153.     if (filePicker.show() != nsIFilePicker.returnOK) {
  154.       // The user canceled, return null.
  155.       GM_log("User canceled file picker dialog");
  156.       return null;
  157.     }
  158.  
  159.     GM_log("User selected: " + filePicker.file.path);
  160.  
  161.     if (filePicker.file.exists() && filePicker.file.isExecutable()) {
  162.       GM_prefRoot.setValue("editor", filePicker.file.path);
  163.       return filePicker.file;
  164.     } else {
  165.       alert(stringBundle.GetStringFromName("editor.please_pick_executable"));
  166.     }
  167.   }
  168. }
  169.  
  170. function launchApplicationWithDoc(appFile, docFile) {
  171.   var args=[docFile.path];
  172.  
  173.   // For the mac, wrap with a call to "open".
  174.   var xulRuntime = Components.classes["@mozilla.org/xre/app-info;1"]
  175.                              .getService(Components.interfaces.nsIXULRuntime);
  176.   if ("Darwin"==xulRuntime.OS) {
  177.     args=["-a", appFile.path, docFile.path]
  178.  
  179.     appFile = Components.classes["@mozilla.org/file/local;1"]
  180.                         .createInstance(Components.interfaces.nsILocalFile);
  181.     appFile.followLinks = true;
  182.     appFile.initWithPath("/usr/bin/open");
  183.   }
  184.  
  185.   var process = Components.classes["@mozilla.org/process/util;1"]
  186.                           .createInstance(Components.interfaces.nsIProcess);
  187.   process.init(appFile);
  188.   process.run(false, args, args.length);
  189. }
  190.  
  191. function parseScriptName(sourceUri) {
  192.   var name = sourceUri.spec;
  193.   name = name.substring(0, name.indexOf(".user.js"));
  194.   name = name.substring(name.lastIndexOf("/") + 1);
  195.   return name;
  196. }
  197.  
  198. function getTempFile() {
  199.   var file = Components.classes["@mozilla.org/file/directory_service;1"]
  200.         .getService(Components.interfaces.nsIProperties)
  201.         .get("TmpD", Components.interfaces.nsILocalFile);
  202.  
  203.   file.append("gm-temp");
  204.   file.createUnique(
  205.     Components.interfaces.nsILocalFile.NORMAL_FILE_TYPE,
  206.     0640
  207.   );
  208.  
  209.   return file;
  210. }
  211.  
  212. function getBinaryContents(file) {
  213.     var ioService = Components.classes["@mozilla.org/network/io-service;1"]
  214.                               .getService(Components.interfaces.nsIIOService);
  215.  
  216.     var channel = ioService.newChannelFromURI(GM_getUriFromFile(file));
  217.     var input = channel.open();
  218.  
  219.     var bstream = Components.classes["@mozilla.org/binaryinputstream;1"]
  220.                             .createInstance(Components.interfaces.nsIBinaryInputStream);
  221.     bstream.setInputStream(input);
  222.  
  223.     var bytes = bstream.readBytes(bstream.available());
  224.  
  225.     return bytes;
  226. }
  227.  
  228. function getContents(file, charset) {
  229.   if( !charset ) {
  230.     charset = "UTF-8"
  231.   }
  232.   var ioService=Components.classes["@mozilla.org/network/io-service;1"]
  233.     .getService(Components.interfaces.nsIIOService);
  234.   var scriptableStream=Components
  235.     .classes["@mozilla.org/scriptableinputstream;1"]
  236.     .getService(Components.interfaces.nsIScriptableInputStream);
  237.   // http://lxr.mozilla.org/mozilla/source/intl/uconv/idl/nsIScriptableUConv.idl
  238.   var unicodeConverter = Components
  239.     .classes["@mozilla.org/intl/scriptableunicodeconverter"]
  240.     .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
  241.   unicodeConverter.charset = charset;
  242.  
  243.   var channel = ioService.newChannelFromURI(GM_getUriFromFile(file));
  244.   var input=channel.open();
  245.   scriptableStream.init(input);
  246.   var str=scriptableStream.read(input.available());
  247.   scriptableStream.close();
  248.   input.close();
  249.  
  250.   try {
  251.     return unicodeConverter.ConvertToUnicode(str);
  252.   } catch( e ) {
  253.     return str;
  254.   }
  255. }
  256.  
  257. function getWriteStream(file) {
  258.   var stream = Components.classes["@mozilla.org/network/file-output-stream;1"]
  259.                          .createInstance(Components.interfaces.nsIFileOutputStream);
  260.  
  261.   stream.init(file, 0x02 | 0x08 | 0x20, 420, -1);
  262.  
  263.   return stream;
  264. }
  265.  
  266. function GM_getUriFromFile(file) {
  267.   return Components.classes["@mozilla.org/network/io-service;1"]
  268.                    .getService(Components.interfaces.nsIIOService)
  269.                    .newFileURI(file);
  270. }
  271.  
  272. /**
  273.  * Compares two version numbers
  274.  *
  275.  * @param {String} aV1 Version of first item in 1.2.3.4..9. format
  276.  * @param {String} aV2 Version of second item in 1.2.3.4..9. format
  277.  *
  278.  * @returns {Int}  1 if first argument is higher
  279.  *                 0 if arguments are equal
  280.  *                 -1 if second argument is higher
  281.  */
  282. function GM_compareVersions(aV1, aV2) {
  283.   var v1 = aV1.split(".");
  284.   var v2 = aV2.split(".");
  285.   var numSubversions = (v1.length > v2.length) ? v1.length : v2.length;
  286.  
  287.   for (var i = 0; i < numSubversions; i++) {
  288.     if (typeof v2[i] == "undefined") {
  289.       return 1;
  290.     }
  291.  
  292.     if (typeof v1[i] == "undefined") {
  293.       return -1;
  294.     }
  295.  
  296.     if (parseInt(v2[i], 10) > parseInt(v1[i], 10)) {
  297.       return -1;
  298.     } else if (parseInt(v2[i], 10) < parseInt(v1[i], 10)) {
  299.       return 1;
  300.     }
  301.   }
  302.  
  303.   // v2 was never higher or lower than v1
  304.   return 0;
  305. }
  306.  
  307. /**
  308.  * Takes the place of the traditional prompt() function which became broken
  309.  * in FF 1.0.1. :(
  310.  */
  311. function gmPrompt(msg, defVal, title) {
  312.   var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
  313.                                 .getService(Components.interfaces.nsIPromptService);
  314.   var result = {value:defVal};
  315.  
  316.   if (promptService.prompt(null, title, msg, result, null, {value:0})) {
  317.     return result.value;
  318.   }
  319.   else {
  320.     return null;
  321.   }
  322. }
  323.  
  324. function ge(id) {
  325.   return window.document.getElementById(id);
  326. }
  327.  
  328.  
  329. function dbg(o) {
  330.   var s = "";
  331.   var i = 0;
  332.  
  333.   for (var p in o) {
  334.     s += p + ":" + o[p] + "\n";
  335.  
  336.     if (++i % 15 == 0) {
  337.       alert(s);
  338.       s = "";
  339.     }
  340.   }
  341.  
  342.   alert(s);
  343. }
  344.  
  345. function delaydbg(o) {
  346.   setTimeout(function() {dbg(o);}, 1000);
  347. }
  348.  
  349. function delayalert(s) {
  350.   setTimeout(function() {alert(s);}, 1000);
  351. }
  352.  
  353. function GM_isGreasemonkeyable(url) {
  354.   var scheme = Components.classes["@mozilla.org/network/io-service;1"]
  355.                .getService(Components.interfaces.nsIIOService)
  356.                .extractScheme(url);
  357.  
  358.   return (scheme == "http" || scheme == "https" || scheme == "file" ||
  359.           scheme == "ftp" || url.match(/^about:cache/)) &&
  360.           !/hiddenWindow\.html$/.test(url);
  361. }
  362.  
  363. function GM_isFileScheme(url) {
  364.   var scheme = Components.classes["@mozilla.org/network/io-service;1"]
  365.                .getService(Components.interfaces.nsIIOService)
  366.                .extractScheme(url);
  367.  
  368.   return scheme == "file";
  369. }
  370.  
  371. function GM_getEnabled() {
  372.   return GM_prefRoot.getValue("enabled", true);
  373. }
  374.  
  375. function GM_setEnabled(enabled) {
  376.   GM_prefRoot.setValue("enabled", enabled);
  377. }
  378.  
  379.  
  380. /**
  381.  * Logs a message to the console. The message can have python style %s
  382.  * thingers which will be interpolated with additional parameters passed.
  383.  */
  384. function log(message) {
  385.   if (GM_prefRoot.getValue("logChrome", false)) {
  386.     logf.apply(null, arguments);
  387.   }
  388. }
  389.  
  390. function logf(message) {
  391.   for (var i = 1; i < arguments.length; i++) {
  392.     message = message.replace(/\%s/, arguments[i]);
  393.   }
  394.  
  395.   dump(message + "\n");
  396. }
  397.  
  398. /**
  399.  * Loggifies an object. Every method of the object will have it's entrance,
  400.  * any parameters, any errors, and it's exit logged automatically.
  401.  */
  402. function loggify(obj, name) {
  403.   for (var p in obj) {
  404.     if (typeof obj[p] == "function") {
  405.       obj[p] = gen_loggify_wrapper(obj[p], name, p);
  406.     }
  407.   }
  408. }
  409.  
  410. function gen_loggify_wrapper(meth, objName, methName) {
  411.   return function() {
  412.      var retVal;
  413.     //var args = new Array(arguments.length);
  414.     var argString = "";
  415.     for (var i = 0; i < arguments.length; i++) {
  416.       //args[i] = arguments[i];
  417.       argString += arguments[i] + (((i+1)<arguments.length)? ", " : "");
  418.     }
  419.  
  420.     log("> %s.%s(%s)", objName, methName, argString); //args.join(", "));
  421.  
  422.     try {
  423.       return retVal = meth.apply(this, arguments);
  424.     } finally {
  425.       log("< %s.%s: %s",
  426.           objName,
  427.           methName,
  428.           (typeof retVal == "undefined" ? "void" : retVal));
  429.     }
  430.   }
  431. }
  432.